//
//  BasicViewController.swift
//  HHSwift
//
//  Created by 华宏 on 2019/1/22.
//  Copyright © 2019年 huahong. All rights reserved.
//

import UIKit

class BasicViewController: BaseViewController {
    
    var string:String = "品味虽贵但不敢减物力，炮制虽繁但不敢省人工"
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        title = "整型、浮点型、字符串、Array、Dictionary"
        
        stringFunc()
        
        tupleFunc()
        
        ArrayFunc()
        
        DictionaryFunc()
        
        //泛型
        var a = 1
        var b = 2
        swapTwo(&a, &b)
       
        
    }
    
//MARK: - 打印
func printFunc() {
       let x = 1,y = true,z = "hello"
       print("x1 =",x)
       print("x2 = \(x)")
       print(x,y,z)
       print(x,y,z, separator: "...")
       print(x,y,z, separator: "...", terminator: ">>>")
   }
  
    
//MARK: - 可选型解包
func OptionalUnpack() {
    
    let errorCode:String? = "404"
    let errorMsg:String? = "Not Found"
    
    //如果errorMsg=nil，则返回nil
    _ = errorMsg?.uppercased()
    _ = errorMsg != nil ? errorMsg : "No Error"
    _ = errorMsg ?? "No Error"
    
    if let errorCode = errorCode,
       let errorMsg = errorMsg,
           errorCode == "405"{
        
        print("\(errorCode + errorMsg)")
    }else
    {
       print("no error")
    }
    
    guard let errorCode1 = errorCode,
          let errorMsg1 = errorMsg else {
        print("no error")
    }
    
     print("\(errorCode1 + errorMsg1)")
    

}
    
//MARK: - 单例模式
 class Manager {
    
    static let defultManager = Manager()
    private init() {
        
    }
}
    
//MARK: - 整型、浮点型

    let number = 1_000_000
    let myFloat = 1.25e-10
    
//统一不同的浮点类型。在这个协议下，可以不用指定这个函数到底是Float还是CGFloat或者是Double，只需要指定他是浮点型FloatingPoint就好了。比如：勾股定理求弦
  func hypotenuse<T:FloatingPoint>(_ a:T,_ b:T) -> T{
      return (a*a + b*b).squareRoot()
  }
  
  //取最小值
  func findMin<T:FloatingPoint>(values:[T]) -> T{
      var result = T.infinity  // Infinity 无穷大
      
      for value in values {
          result = result < value ? result : value
      }
      return result
      
  }
  
 
  // 除法
  func divide<T:FloatingPoint>(_ a:T,_ b:T) -> T {
      if b.isZero {
          return T.nan // NaN (Not a Number)
      }
      
      return a / b
  }


//MARK: - 字符串
   
    func stringFunc() -> Void {
      
        /** \()转译字符 相当于stringWithFormat: */
           var appengStr = "hello \(string)"
               appengStr += "swift"
           
           
            /** 字符串比较 */
           let _:Bool = "str1" == "str2"
           
           //隐式可选型，使用时可以不解包
           let _:String! = nil
           
           let _ =  string.uppercased()
           let _ =  string.lowercased()
           let _ =  string.contains("helle")
           let _ =  string.capitalized
           let _ =  string.hasPrefix("hi")
           let _ =  string.hasSuffix("hi")
           
           let _ = String(format: "hi:%@", "hi")
           
           /** 遍历字符串 */
           for s in string {
               print(s)
           }
           
           /** 字符串的长度 */
           let length1 = string.lengthOfBytes(using: String.Encoding.unicode)
           print("\"length1:",length1) //"utf8: 6,unicode:4
           
           let length2:Int = string.count
           print("\"length2:",length2) //2
           
           
          //无返回值,改变自身
           var str = "Hello, Swift"
           str.append("!")
        
           //有返回值,不改变自身
           _ =  str.appending(" Hello, world!")
    }
    
    //字符串截取
    func subString() -> Void {
        
        /** 转换并截取 */
        let _ = (string as NSString).substring(with: NSMakeRange(5, 10))
        
        /** 截取前10个 */
        let subStr1 = string.prefix(10)
        print(subStr1)
        
        /** 截取后10个 */
        let subStr2 = string.suffix(10)
        print(subStr2)
        
        /** 截取（5，15） */
        let index1 = string.index(string.startIndex, offsetBy: 5)
        let index2 = string.index(string.endIndex, offsetBy: -5)
//        let subStr3 = string[index1..<index2]
        let subStr3 = string[...index2]
        print(subStr3)
        
        //range
        let index3 = string.index(before: index1)
        let index4 = string.index(after: index2)
        let range = index3..<index4
        string.replaceSubrange(range, with: "hi")
        string.append("hello")
        string.insert(contentsOf: "hello", at: index1)
        string.insert("!", at: string.endIndex)
        string.remove(at: index4)
        string.removeSubrange(range)
        
    }
    
   
//MARK: - 元组
    func tupleFunc() -> Void {
      
        var tuple1:(Int,Int) = (5,2)
             tuple1 = (2,5)
         let (_,_) = tuple1
         
         let tuple2:(code:Int,message:String) = (404,"Not Found")
         let (code,message) = tuple2
         print("code:\(code),message:\(message)")
         let _ = tuple2.code
         let _ = tuple2.message
        
         
         let isTrue = (4,5) > (2,5)
         print("isTrue:\(isTrue)")
    }
    
//MARK: - Array
   
    func ArrayFunc() -> Void {
      
        var arr:Array = ["1","2","3","4","5"]

        let _ = Array<Int>(repeating: 0, count: 5)
        let _ = [Int](repeating: 0, count: 8)
        
        
        let arr2 = ["aca","cbb"]
        
        let _ = arr.count
        let _ = arr.isEmpty
        let _ = arr.min()
        let _ = arr.max()
        let _ = arr.firstIndex(of: "4")
        let _ = arr.index(after: 2)
        let _ = arr.index(before: 2)
       
        
        let arr3 = arr + arr2
        print("arr3:\(arr3)")
        
        var arr4 = ["333","ccc",20] as [Any]
        print("arr4:\(arr4)")
        
        //取[0,arr1.count)范围的值
       let _ = arr[0..<arr.count]
        
        /** 数组遍历 */
        for str in arr4 {
            print(str)
        }
        
        for (index,value) in arr4.enumerated() {
          print(index)
          print(value)

        }
        
        /** 添加数组元素 */
        arr4.append("555")
        print("arr4:\(arr4)")
        arr4.insert("666", at: 2)
        
        /** 修改数组元素 */
        arr4[0] = "000"
        print("arr4:\(arr4)")
        
        /** 删除数组元素 */
        arr4.remove(at: 1)
        print("arr4:\(arr4)")
        
        arr4.removeFirst()
        print("arr4:\(arr4)")
        
        arr4.removeLast()
        print("arr4:\(arr4)")
        
        arr4.removeAll()
        print("arr4:\(arr4)")
        
        //映射
        var arr5 = arr.map { (str) -> Int in
            return Int(str)!
        }
        
        //过滤
       arr5 =  arr5.filter { (number) -> Bool in
            return number < 5
        }
        
        //聚合
        let new_arr5 =  arr5.reduce(10, {x,y in
//            print("x:\(x)")
//            print("y:\(y)")
            x + y
        })
        
        print("new_arr5:\(new_arr5)")
      
        //有返回值,不改变自身
        _ = arr.reversed()
        _ = arr.sorted()
        _ = arr.sorted(by: >)
        
        //无返回值,改变自身
        arr.reverse()
        arr.sort()
        arr.sort(by: >)
    }
  
    
//MARK: - Dictionary
        
    func DictionaryFunc() {
          
        // 创建空字典
          _ = [String:Int]()
          _ = Dictionary<String,String>()
          let _:[String:Int] = [:]
          let _:Dictionary<String,String> = [:]
          
          
          var dict:Dictionary = ["name":"华宏","age":18] as [String:Any]
          var _:[String:Any] = ["name":"华宏","age":18]
          
         _ = dict.isEmpty
          
          /** 增加健值对 */
          dict["tag"] = "男神"
          print(dict)
          
          /** 根据key 修改value */
          dict["age"] = 20
         var oldvalue =  dict.updateValue(30, forKey: "new")
          
          /** 删除 */
          oldvalue =  dict.removeValue(forKey: "age")
          
          dict["age"] = nil
          
          //keys
          let _ = Array(dict.keys)
          
          /** 字典的遍历 */
          for (key,value) in dict {
              print("key:\(key),value:\(value)")
          }
    }
        
        
        
//MARK:Set
    
    func SetFunc() {
        
        // 必须显示声明类型，不然会被认为是数组
        let _:Set<String> = []
        _ = Set<String>()
        
        var set:Set<Int> = [1,2,3,4,5]
        set = Set([1,2,3,4,5])
        
        set.insert(6)
       let old = set.remove(7)
        if let old = old {
            print(old)
        }
        
        _ = set.count
        _ = set.isEmpty
        _ = set.first
        _ = set.contains(1)
        
        for i in set {
            print(i)
        }
        
        _ = set == Set([1,2,3,4,5])
        
        
        var setA = Set([1,2,3,4,5])
        let setB:Set = [1,3,5]
        
        // 并
        let _ = setA.union(setB)
        let _ = setA.formUnion(setB)        //swift 3
        // 操作对象可以是数组
       let _ =  setA.union([1,5])
        
        // 交
        let _ = setA.intersection(setB)         //swift 3
        let _ = setA.formIntersection(setB)     //swift 3
        
        
        // 减
        let _ = setA.subtracting(setB)            //swift 3 这个才是swift2中subtract的真正方法
        let _ = setA.subtract(setB)               //swift 3 这个的意思等同于subtractInPlace, 不要搞混
        
        
        // 异或
        let _ = setA.symmetricDifference(setB)      //swift 3
        let _ = setA.formSymmetricDifference(setB)  //swift 3
        
        // 子集
        let _ = setA.isSubset(of: setB)           //swift 3
        let _ = setA.isStrictSubset(of: setB)     //swift 3
        
        // 超集
        let _ = setA.isSuperset(of: setB)         //swift 3
        let _ = setA.isStrictSuperset(of: setB)   //swift 3
        
        // 判断相离
        let _ = setA.isDisjoint(with: setB)       //swift 3
    }
    
    
//MARK: - 泛型
  //交换两个值
    func swapTwo<T>(_ a:inout T,_ b:inout T) {
        (a,b) = (b,a)
    }
   
    

}


//MARK: - 别名

protocol WeightCalculable {
    associatedtype WeightType
    var weight : WeightType {get}
    
}

class iPhone: WeightCalculable {
    typealias WeightType = Double
    var weight: WeightType{
        return 0.114
    }
}
